package cn.zk.base;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;

import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;

/**
 * ClassName: ZkClientThird
 * Desc: 权限的使用等
 * Date： 2016/12/5
 * Created：shaom
 */
public class ZkClientThird implements Watcher {


    private static final CountDownLatch downLatch = new CountDownLatch(1);
    public static final String connectString = "master:2181,slave01:2181,slave02:2181";
    private static ZooKeeper zkClient;

    public ZkClientThird() {
        try {
            getZkClient();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 基本的客户端实例
     * 创建客户端是一个异步的过程
     * @throws Exception
     */
    void getZkClient() throws Exception {
        zkClient = Objects.isNull(zkClient) ? new ZooKeeper(connectString, 2000, this) : zkClient;
        downLatch.await();
    }

    /**
     * 创建复用sessionId、sessionPasswd的客户端
     *
     * @throws Exception
     */
    void getClient() throws Exception {
        zkClient = Objects.isNull(zkClient) ? new ZooKeeper(connectString, 2000, this) : zkClient;
        downLatch.await();


        long sessionId = zkClient.getSessionId();
        byte[] sessionPasswd = zkClient.getSessionPasswd();

        // 使用错误的 sessionId 和 sessionPasswd，收到Expire
        zkClient = new ZooKeeper(connectString, 2000, this, 1L, "test".getBytes());

        // 复用 sessionId 和 sessionPasswd
        zkClient = new ZooKeeper(connectString, 2000, this, sessionId, sessionPasswd);

    }

    /**
     * 权限控制
     *
     * @throws IOException
     * @throws KeeperException
     * @throws InterruptedException
     */
    void acl() throws IOException, KeeperException, InterruptedException {

        zkClient.addAuthInfo("digest", "user:pwd".getBytes());//添加权限
        zkClient.create("/testAuth", "auth".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        zkClient.create("/testAuth/child", "child".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

        // 新建没有权限的客户端
        zkClient = new ZooKeeper(connectString, 2000, this);
        zkClient.getData("/testAuth", true, null);//没有权限会报错

        zkClient.delete("/testAuth/child", -1);//报错
        zkClient.delete("/testAuth", -1);//可以删除，注意没有权限也可以删除。删除节点权限比较特殊
    }

    @Override
    public void process(WatchedEvent event) {
        System.out.println("状态 ： " + event.getState());
        System.out.println("path : " + event.getPath());
        System.out.println("已经触发了 " + event.getType() + " 事件！");

        if (Event.KeeperState.SyncConnected == event.getState()) {
            downLatch.countDown();

            switch (event.getType()) {
                case NodeCreated:
                    System.out.println("NodeCreated~~~");
                    break;
                case NodeDeleted:
                    System.out.println("NodeDeleted~~");
                    break;
                case NodeDataChanged:
                    System.out.println("NodeDataChanged~~");
                    break;
                case NodeChildrenChanged:
                    System.out.println("NodeChildrenChanged~~");
                    break;
                default:
                    System.out.println("default ~~~");
            }
        }
    }
}
